package com.hd.manager.util;

import net.coobird.thumbnailator.Thumbnails;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Encoder;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Base64;
import java.util.Objects;

import static com.hd.manager.config.Constant.imageFilePath;

/**
 * @projectName:    entrance_guard 
 * @package:        com.hd.manager.util
 * @className:      ImageUtil
 * @author:     otto
 * @description:  
 * @date:    2023/7/26 8:53
 * @version:    1.0
 */ 

@Component
public class ImageUtil {
    /**
     *
     * @param path
     * @return String
     * @description 将文件转base64字符串
     * @date 2018年3月20日
     * @author changyl
     */
    public String fileToBase64(String path) {
        byte[] data = null;
        // 读取图片字节数组
        try {
            InputStream in = new FileInputStream(path);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        // 返回Base64编码过的字节数组字符串
        return "data:image/jpg;base64,"+encoder.encode(Objects.requireNonNull(data));
    }

    /**
     * 提供base64文件和父路径下的保存文件路径 返回绝对路径
     * @param base64 base64文件
     * @param fileName 父路径下的保存文件路径
     * @return 返回绝对路径
     */
    public static String base64ToFile(String base64,String filePath, String fileName) {
        File file = null;
        //创建文件目录

        File  dir=new File(filePath);
        if (!dir.exists() && !dir.isDirectory()) {
            dir.mkdirs();
        }
        BufferedOutputStream bos = null;
        java.io.FileOutputStream fos = null;
        try {
            byte[] bytes = Base64.getDecoder().decode(base64);
            file=new File(filePath+"\\"+fileName);
            fos = new java.io.FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return filePath+"\\"+fileName;
    }

    /**
     * 图片转blob
     * @param filePath
     * @return
     */
    public byte[] fileToBlob(String filePath){
        //图片转化为二进制
        byte[] imageBytes = null;
        try (FileInputStream fileInputStream = new FileInputStream(new File(filePath));) {
            imageBytes = new byte[fileInputStream.available()];
            fileInputStream.read(imageBytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return imageBytes;
    }

    /**
     * 二进制转图片保存
     * @param imageBytes
     * @param savePath
     */
    public void blobToPicture(byte[] imageBytes,String savePath){
        try (FileOutputStream fileOutputStream = new FileOutputStream(new File(savePath));) {
            fileOutputStream.write(imageBytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 图片压缩
     */
    /**
     * @author kcy
     * @version 2018-11-8
     * @param oldImg   原图片路径
     * @param newsImg  压缩后新文件路径
     * @param width    宽
     * @param height   高
     * @param quality  图片质量 (0 - 1.0f)浮点型
     */
    public void ImageCompression(String oldImg,String newsImg,int width, int height, Float quality) throws IOException {
        /**
         Thumbnails.of() <- 这个方法虽然可以直接使用原图路径读取图片,但是有很大几率会使压缩后的图片颜色失真。
         也建议不要用ImageIO.read()这种方法读取图片，灰常容易失真!
         **/
        //使用Toolkit.getDefaultToolkit().getImage()读取图片，防止图片颜色失真。
        Image image = Toolkit.getDefaultToolkit().getImage(oldImg);

        //Image转换BufferedImage
        BufferedImage bufferedImage = this.toBufferedImage(image);

        //图片压缩
        Thumbnails.of(bufferedImage).
                //新图片宽高
                        size(width, height).
                //新图片后缀
                        outputFormat("jpg").
                //保持长宽比例
                        keepAspectRatio(false).
                //压缩质量
                        outputQuality(quality).
                //新图片路径
                        toFile(newsImg);
    }

    private BufferedImage toBufferedImage(Image image) {
        if (image instanceof BufferedImage) {
            return (BufferedImage) image;
        }
        // This code ensures that all the pixels in the image are loaded
        image = new ImageIcon(image).getImage();
        BufferedImage bimage = null;
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        try {
            int transparency = Transparency.OPAQUE;
            GraphicsDevice gs = ge.getDefaultScreenDevice();
            GraphicsConfiguration gc = gs.getDefaultConfiguration();
            bimage = gc.createCompatibleImage(image.getWidth(null), image.getHeight(null), transparency);
        } catch (HeadlessException e) {
            // The system does not have a screen
        }
        if (bimage == null) {
            // Create a buffered image using the default color model
            int type = BufferedImage.TYPE_INT_RGB;
            bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
        }
        // Copy image to buffered image
        Graphics g = bimage.createGraphics();
        // Paint the image onto the buffered image
        g.drawImage(image, 0, 0, null);
        g.dispose();
        return bimage;
    }

    /**
     *
     * @param pictureId 图片唯一识别码
     * @param image base64
     * @return
     */
    public String savePicture(String pictureId, String image){
        String path = pictureId+".jpg";
        String imagenoPrefix = image.substring( image.indexOf( "," ) + 1 );
        File file = new File(path);
        String globalPath = imageFilePath+"\\"+path;
        // 存储图片
        if(!file.exists())
            globalPath = ImageUtil.base64ToFile(imagenoPrefix,imageFilePath,path);
        return globalPath;
    }
}
